<html> 
 
<head> 
<title>006 | Particle stream | J3D</title> 

<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> 

<link rel="stylesheet" href="common/common.css"/>
<script type="text/javascript" src="common/common.js"></script>

<script type="text/javascript" src="../build/j3d.js"></script>

<script id="particleShader" type="x-shader/x-vertex"> 
	//#name ParticleShader
	//#include CommonInclude
	
	//#vertex
	//#include VertexInclude
	attribute vec2 aVertexAnimation;
	
	varying vec4 vColor;
	varying float eyeDist;
	varying float orderPos;
	
	void main(void) {
	
		orderPos = mod(aVertexAnimation.x - uTime * 0.5, 1.0);
	
		float a = aVertexPosition.x - uTime * 0.4;
		float b = aVertexPosition.y * uTime * 5.0;
		
		float r = 27.5 + 5.0 * sin(a * 8.0);		
		vec3 knotPos = vec3(cos(a * 5.0) * r, sin(a * 4.0) * r, cos(a * 8.0) * r * 2.0); 
		
		float z = aVertexPosition.z;
		vec3 orbitPos = vec3(cos(b) * z, sin(b) * z, cos(b) * z);
		
		vec4 worldPos = mMatrix * vec4(knotPos + orbitPos, 1.0);
		
		vColor = aVertexColor;
		eyeDist = clamp( distance( uEyePosition, worldPos.xyz ) / 240.0, 0.0, 1.0);
		
		gl_Position = pMatrix * vMatrix * worldPos;
		gl_PointSize = 30.0 * (1.0 - eyeDist);
	}

	//#fragment
	uniform vec4 uColor;
	uniform sampler2D uParticleTex;
	
	varying vec4 vColor;
	varying float eyeDist;
	varying float orderPos;
	
	void main(void) {
		vec4 texCol = texture2D(uParticleTex, gl_PointCoord);
		vec3 indCol = vec3(orderPos, orderPos, 0.5 - orderPos);
		gl_FragColor = vec4( indCol * vec3(1.0 - eyeDist) * uColor.rgb, texCol.a * (1.0 - eyeDist) );
	}
</script>

<script>
	var engine, stars, camera;
	var mx, my = 0;

	function init() {
		if(!checkWebGL()) return;

		engine = new J3D.Engine();

		camera = new J3D.Transform();
		camera.camera = new J3D.Camera();
		camera.position.z = 100;	
		engine.camera = camera;	

		stars = new J3D.Transform();	
		
		var shsrc = document.getElementById("particleShader").firstChild.nodeValue;
		stars.renderer = new J3D.ShaderUtil.parseGLSL(shsrc);
		stars.renderer.drawMode = gl.POINTS;
		stars.renderer.uColor = [0.8, 0.3, 0.2, 1];
		stars.renderer.uParticleTex = new J3D.Texture("models/textures/smoke.png");

		var a = getParticleAmount();	
		stars.geometry = new J3D.Geometry();
		stars.geometry.addArray("aVertexPosition", distributeAngles(a), 3);
		stars.geometry.addArray("aVertexColor", J3D.ParticleUtil.randomColors(a, 0, 1), 4);
		stars.geometry.addArray("aVertexAnimation", prepareAnimationAttributes(a, 8), 2);

		stars.geometry.setTransparency(true, gl.SRC_ALPHA, gl.DST_ALPHA);
			
		engine.scene.add(stars, camera);

		document.onmousemove = onMouseMove;
		
		draw();
	}
	
	function prepareAnimationAttributes(amount, maxOffset) {
		var animdata = new Float32Array(amount * 2);

		for (var i = 0; i < amount * 2; i++) {
			animdata[i] = i / (amount * 2) + Math.random() * 0.05;
		}
	
		return animdata;
	}
	
	function distributeAngles(amount, origin) {
		var vertices = new Float32Array(amount * 3);
		
		var step = Math.PI * 0.25 / amount;
		
		origin = origin || v3.ZERO();	
		
		for (var i = 0; i < amount * 3; i += 3) {
			vertices[i] = step * i / 3;
			vertices[i + 1] = Math.random();
			vertices[i + 2] = (1 + ((amount * 1.5) - Math.abs(i - amount * 1.5)) / (amount * 0.15)) * (0.1 + Math.random());
		}
		
		return vertices;
	}

	function onMouseMove(e) {
		mx = ( e.clientX / window.innerWidth  ) * 2 - 1;
		my = ( e.clientY / window.innerHeight ) * 2 - 1;
	}
	
	function getParticleAmount() {
		return 7500;
	}
	
	function draw() {
		requestAnimationFrame(draw);
		engine.render();
	}
	
</script>

</head> 

<body onload="init();">
	<script>
		setLabels("006. Particle stream", "A stream of textured particles<br>animated with a vertex shader");
	</script>
	
<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-24294554-1']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

</body> 

</html> 